package com.hzlj.position.job.listener;

import cn.hutool.core.util.ObjectUtil;
import com.fz.common.kafka.annotation.KafkaListenerDelay;
import com.fz.common.kafka.annotation.KafkaListenerRetry;
import com.hzlj.position.config.common.dto.jzJbxxDeviceBind.JzJbxxDeviceBindMsgDTO;
import com.hzlj.position.config.common.dto.jzJbxxDeviceBind.JzJbxxDeviceBindQueryResultDTO;
import com.hzlj.position.config.common.dto.jzJbxxDeviceBind.JzJbxxDeviceBindSimpleQueryParamDTO;
import com.hzlj.position.config.common.enums.CRUDEnum;
import com.hzlj.position.config.common.enums.ChannelType;
import com.hzlj.position.config.config.PositionConfig;
import com.hzlj.position.config.service.JzJbxxDeviceBindService;
import com.hzlj.position.config.service.OperatorConfigService;
import com.hzlj.position.config.service.WdConfigService;
import com.hzlj.position.job.job.LocateTimerTaskJob;
import com.hzlj.position.job.job.OperatorTimerTaskJob;
import com.hzlj.position.job.job.WdTimerTaskJob;
import com.hzlj.position.locate.service.ReportInitiativeService;
import com.hzlj.position.locate.service.ReportInitiativeSettingJzryService;
import com.hzlj.position.locate.service.ReportInspectionService;
import com.hzlj.position.locate.service.ReportVideoService;
import com.hzlj.sqjz.jz.common.dto.jzJbxx.JzJbxxSjhUpdateDTO;
import com.hzlj.sqjz.jz.service.JzJbxxService;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import static com.hzlj.position.config.common.constant.Topic.DEVICE_BIND;


/**
 * @author lifh
 * @date 2023/3/17 11:29
 **/
@Slf4j
@Component
public class JzJbxxDeviceBindListener {
    @Resource
    private OperatorTimerTaskJob operatorTimerTaskJob;
    @Resource
    private WdTimerTaskJob wdTimerTaskJob;
    @Resource
    private JzJbxxDeviceBindService jzJbxxDeviceBindService;
    @Resource
    private ReportInitiativeService reportInitiativeService;
    @Resource
    private ReportInspectionService reportInspectionService;
    @Resource
    private ReportVideoService reportVideoService;
    @Resource
    private OperatorConfigService operatorConfigService;
    @Resource
    private WdConfigService wdConfigService;
    @Resource
    private ReportInitiativeSettingJzryService reportInitiativeSettingJzryService;
    @Resource
    private PositionConfig positionConfig;
    @Resource
    private JzJbxxService jzJbxxService;

    @KafkaListenerRetry(enable = false)
    @KafkaListenerDelay(delay = "5", delayUnit = TimeUnit.SECONDS)
    @KafkaListener(topics = {DEVICE_BIND})
    public void jzJbxxDeviceBind(ConsumerRecord<String, JzJbxxDeviceBindMsgDTO> record) {
        log.info("【kafka】收到设备同步消息:{}", record.value());
        JzJbxxDeviceBindMsgDTO bind = record.value();
        try {
            //删除上报时间配置
            if (Boolean.TRUE.equals(record.value().getDelLocateTimes())) {
                this.reportInitiativeSettingJzryService.deleteReportInitiativeSettingJzry(bind.getBind().getJzId());
            }
        } catch (Exception e) {
            log.info("【kafka】设备同步消息异常(删除主动点验配置):{}", bind, e);
        }
        try {
            //同步手机号
            syncSjh(record);
        } catch (Exception e) {
            log.info("【kafka】腕带同步信息:{}", bind, e);
        }
        try {
            //运营商的task
            operatorTimerTask(record);
        } catch (Exception e) {
            log.info("【kafka】设备同步消息异常(运营商的task):{}", bind, e);
        }
        try {
            //腕带的task
            wdTimerTask(record);
        } catch (Exception e) {
            log.info("【kafka】设备同步消息异常(运营商的task):{}", bind, e);
        }
        try {
            //点验信息
            report(record);
        } catch (Exception e) {
            log.info("【kafka】设备同步消息异常(点验信息):{}", bind, e);
        }
    }


    /**
     * 运营商的task
     */
    private void operatorTimerTask(ConsumerRecord<String, JzJbxxDeviceBindMsgDTO> record) {
        JzJbxxDeviceBindMsgDTO msg = record.value();
        JzJbxxDeviceBindQueryResultDTO bind = msg.getBind();
        OperatorConfigService.OperatorTaskConfig operatorTaskConfig = operatorConfigService.taskConfig(bind.getJgCode(), bind.getChannel());
        if (operatorTaskConfig == null) {
            return;
        }
        addOrCancelTask(CRUDEnum.of(msg.getCrud()), bind, operatorTimerTaskJob);
    }


    /**
     * wd的task
     */
    private void wdTimerTask(ConsumerRecord<String, JzJbxxDeviceBindMsgDTO> record) {
        JzJbxxDeviceBindMsgDTO msg = record.value();
        JzJbxxDeviceBindQueryResultDTO bind = msg.getBind();
        WdConfigService.WdTaskConfig wdTaskConfig = wdConfigService.taskConfig(bind.getJgCode(), bind.getChannel());
        if (wdTaskConfig == null) {
            return;
        }
        addOrCancelTask(CRUDEnum.of(msg.getCrud()), bind, wdTimerTaskJob);

        //更新定位间隔
        if (ObjectUtil.isEmpty(bind.getLocateInterval())
                || ObjectUtil.isEmpty(bind.getDeviceCode())) {
            return;
        }
        switch (CRUDEnum.of(msg.getCrud())) {
            case ADD:
            case UPDATE:
            case UPDATE_DEVICE_CODE:
                wdTimerTaskJob.updateLocateInterval(bind.getJgCode(), bind.getJzId(), bind.getDeviceCode(), bind.getChannel(), bind.getLocateInterval());
                break;
            default:
                break;
        }
    }

    private void addOrCancelTask(CRUDEnum crud,
                                 JzJbxxDeviceBindQueryResultDTO bind,
                                 LocateTimerTaskJob locateTimerTaskJob) {
        switch (crud) {
            case DEL:
                locateTimerTaskJob.cancelTask(bind.getJgCode(), bind.getJzId(), bind.getDeviceCode(), bind.getChannel());
                break;
            case ADD:
            case UPDATE:
            case UPDATE_DEVICE_CODE:
                locateTimerTaskJob.addTask(bind.getJgCode(), bind.getJzId(), bind.getDeviceCode(), bind.getChannel(), bind.getLocateInterval());
                break;
            default:
                break;
        }
    }

    /**
     * 同步手机号
     */
    private void syncSjh(ConsumerRecord<String, JzJbxxDeviceBindMsgDTO> record) {
        if (!positionConfig.getJz().getSjhSync()) {
            return;
        }
        JzJbxxDeviceBindMsgDTO msg = record.value();
        JzJbxxDeviceBindQueryResultDTO bind = msg.getBind();
        if (!ObjectUtil.equal(ChannelType.MOBILE.getCode(), bind.getChannelType())) {
            return;
        }
        String sjh = bind.getDeviceCode();
        if (CRUDEnum.of(msg.getCrud()) == CRUDEnum.DEL) {
            sjh = null;
        }
        JzJbxxSjhUpdateDTO dto = new JzJbxxSjhUpdateDTO();
        dto.setJzId(bind.getJzId());
        dto.setSjh(sjh);
        log.info("将定位号码同步到手机号:dto={}", dto);
        jzJbxxService.updateJzJbxxSjh(dto);
    }

    /**
     * 点验信息
     */
    private void report(ConsumerRecord<String, JzJbxxDeviceBindMsgDTO> record) {
        JzJbxxDeviceBindMsgDTO msg = record.value();
        JzJbxxDeviceBindQueryResultDTO bind = msg.getBind();
        //判断是否是app信息
        JzJbxxDeviceBindSimpleQueryParamDTO param = jzJbxxDeviceBindService.getQueryParam4App();
        if (!ObjectUtil.equal(bind.getChannelType(), param.getChannelType())) {
            return;
        }
        String jzId = bind.getJzId();
        Date now = new Date(record.timestamp());
        switch (CRUDEnum.of(msg.getCrud())) {
            case DEL:
                reportInitiativeService.delete(jzId, now);
                reportInspectionService.delete(jzId, now);
                reportVideoService.delete(jzId, now);
                break;
            case ADD:
            case UPDATE:
            case UPDATE_DEVICE_CODE:
                reportInitiativeService.sync(jzId);
                break;
            default:
                break;
        }
    }
}
